package controller

import (
	"beergo/lib/tool"
	"encoding/json"
	"github.com/beego/beego/v2/client/orm"
	"reflect"
	"strconv"
)

func (this BaseController) GetOrm() orm.Ormer {
	o := orm.NewOrm()
	return o
}

func (this BaseController) FillModel(model interface{}) error {
	return json.Unmarshal(this.Ctx.Input.RequestBody, &model)
}

func (this BaseController) FillModelRelated(model interface {
	FillFk(name string, id int) orm.Ormer
	FillList(name string, ids []int) orm.Ormer
	//GetReflect() reflect.Type
}) error {
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &model)
	data := this.GetBodyParamAll()
	this.LogOut(data)
	for index, _ := range data {
		this.LogOut(index)
		model.FillFk(index, this.GetBodyParamInt(index))
		model.FillList(index, this.GetBodyParamIntSlice(index))
	}
	return err
}

func (this BaseController) JsonParseModel(model interface {
	GetReflect() reflect.Type
}) ([]string, error) {
	data := this.GetBodyParamAll()
	types := model.GetReflect()
	fieldsBox:=make(map[string]reflect.StructField)
	for i := 0; i < types.NumField(); i++ {
		ff:=types.Field(i)
		fieldsBox[ff.Name] = ff
	}
	var fields []string
	for index, _ := range data {
		f, findIt := fieldsBox[tool.Ucfirst(index)]
		if findIt {
			fields = append(fields, index)
			//判断是fk类型
			if f.Type.String()[0:1] == "*" {
				if data[index] == "" {
					data[index] = nil
				} else {
					data[index] = tool.StringKeyMap{"id": data[index]}
				}
			}
			if f.Type.String()[0:2] == "[]" && f.Tag.Get("flag") == "M2M" {
				if data[index] == "[]" {
				} else {
					//断言传值的内容
					v, ok := data[index].([]interface{})
					arr := make([]tool.StringKeyMap, 0)
					if ok {
						for _, item := range v {
							arr = append(arr, tool.StringKeyMap{"id": item})
						}
					} else {
						println("断言失败")
					}
					data[index] = arr
				}
			}else if f.Type.String()[0:2] == "[]" && f.Tag.Get("flag") == "O2M" {
				delete(data, index)
			}
			if f.Tag.Get("edit_type") == "json" {
				if reflect.TypeOf(data[index]) != nil && reflect.TypeOf(data[index]).String() != "string" {
					tmp, _ := json.Marshal(data[index])
					data[index] = string(tmp)
				}
			}
			if f.Type.String() == "int" && reflect.TypeOf(data[index]).String() == "string" {
				tmp, _ := strconv.Atoi(data[index].(string))
				data[index] = tmp
			}
			if f.Type.String() == "int" && reflect.TypeOf(data[index]).String() == "float64" {
				tmp:= int(data[index].(float64))
				data[index] = tmp
			}
			if f.Type.String() == "int64" && reflect.TypeOf(data[index]).String() == "string" {
				tmp, _ := strconv.ParseInt(data[index].(string), 10, 64)
				data[index] = tmp
			}
			if f.Type.String() == "int64" && reflect.TypeOf(data[index]).String() == "float64" {
				tmp:= int64(data[index].(float64))
				data[index] = tmp
			}
			if f.Type.String() == "int32" && reflect.TypeOf(data[index]).String() == "string" {
				tmp, _ := strconv.ParseInt(data[index].(string), 10, 32)
				data[index] = int32(tmp)
			}
			if f.Type.String() == "int32" && reflect.TypeOf(data[index]).String() == "float64" {
				tmp:= int32(data[index].(float64))
				data[index] = tmp
			}
			if f.Type.String() == "float64" && reflect.TypeOf(data[index]).String() == "string" {
				tmp, _ := strconv.ParseFloat(data[index].(string), 64)
				data[index] = tmp
			}
			if f.Type.String() == "float32" && reflect.TypeOf(data[index]).String() == "string" {
				tmp, _ := strconv.ParseFloat(data[index].(string), 32)
				data[index] = float32(tmp)
			}
		}else {
			delete(data, index)
		}
	}
	jsonData, err := json.Marshal(data)
	if err != nil {
		return fields, err
	}
	err = json.Unmarshal(jsonData, &model)
	if err != nil {
		println("json Unmarshal err",err.Error())
		return fields, err
	}
	return fields, nil
}

func (this BaseController) FillM2M(model interface {
	FillList(name string, ids []int) orm.Ormer
}) {
	data := this.GetBodyParamAll()
	for index, _ := range data {
		model.FillList(index, this.GetBodyParamIntSlice(index))
	}
}
